/**
 * @author yaoyuan
 * @version 1.0
 * @name zjzcVotingApp.Service: uiService
 * @description 用户登录
 */
'use strict';

angular.module('zjzcVotingApp')
    .service('uiService', ['$rootScope', '$window', 'http', function($rootScope, $window, http) {

    //-------------- DOM操作的兼容性方法 --------------
    var appDom = (function() {
        return {
            nextElementSibling: function(element) {
                var _next = function(element) {
                    var nextElement = element.nextSibling;
                    if(!nextElement || nextElement.nodeType === 1) return nextElement;
                    else  return _next(nextElement);
                }
                return _next(element);
            },
            previousElementSibling: function(element) {
                var _previous = function(element) {
                    var previousElement = element.previousSibling;
                    if(!previousElement || previousElement.nodeType === 1) return previousElement;
                    else return _previous(previousElement);
                }
                return _previous(element);
            }
        };
    })();
    //-------------- AJAX请求模式模块 --------------
    var appAjax = (function() {
        /**
         * [_addConfig 添加必要的配置参数]
         */
        var _addConfig = function(config) {
            if(appCommon.type(config) == 'string') {
                config = {
                    url: config,
                    module: 'default'
                };
            }
            config.module =  config.module || 'default';
            return config;
        }
        /**
         * [_module 请求模式]
         * 根据接口的module配置寻找适用的请求模式
         * 默认为default或者自动添加该模式
         */
        var _module = {
            /**
             * [base 基本请求模式]
             */
            base: function(params, config) {
                var params = params || {};
                params.method = config.url;
                if(config.params) {
                    params = angular.extend(config.params, params);
                }
                if(config.method && config.method.toLowerCase() == 'post') {
                    return http.post(params);
                }
                return http.ajax(params);
            },
            /**
             * [default 默认模式]
             *  支持示例如下
             *  1. key: url // url 为接口地址
             *  2. key: {
             *      url: url,
             *      method: 'post',     //可选  请求方式默认为get
             *      module: 'default'   //可选  默认为default
             *      params: {key: val}  //可选  额外添加的参数
             *     }
             */
            default: function(config) {
                return function(params) {
                    return _module.base(params, config);
                }
            },
            /**
             * [parameter 单参数模式]
             * 支持示例如下
             * 1. key: {
             *      url: url,
             *      method: 'post',     //可选  请求方式默认为get
             *      module: 'parameter'
             *      parameter: key  //必选 传值对于的key对象
             *     }
             */
            parameter: function(config) {
                return function(val) {
                    var params = {};
                    params[config.parameter] = val;
                    return _module.base(params, config);
                }
            },
            /**
             * [method 调用方法模式]
             * 支持示例如下
             * 1. key: {
             *      url: url,           //必选  二次调用改服务中以url为关键key值的方法
             *      method: 'post',     //可选  请求方式默认为get
             *      module: 'method'
             *      params: {key: val}  //可选  额外添加的参数
             *     }
             */
            method: function(config, configs) {
                return function(params) {
                    var params = params || {};
                    if(config.params) {
                        params = angular.extend(config.params, params);
                    }
                    var _config = configs[config.url];
                    if(appCommon.type(_config) == 'function') {
                        return configs[config.url](params);
                    }else{
                        _config = _addConfig(_config);
                        return _module[_config.module](_config, configs)(params);
                    }
                }
            }
        };

        return {
            ajaxModule: function(configs) {
                var _obj = {};
                for(var i in configs) {
                    configs[i] = _addConfig(configs[i]);
                    //console.log(i);
                    _obj[i] = _module[configs[i].module](configs[i], configs);
                }
                return _obj;
            }
        };
    })();
    //-------------- 公共模块的方法 --------------
    var appCommon = (function() {

        var classtype = {};
        // Populate the classtype map
        "Boolean Number String Function Array Date RegExp Object".split(" ").forEach(function(name, i) {
            classtype["[object " + name + "]"] = name.toLowerCase();
        });
        // String format
        String.format = function(format){
            var args = Array.prototype.slice.call(arguments, 1);
            return format.replace(/\{(\d+)\}/g, function(m, i){
                return args[i];
            });
        }
        String.prototype.formatDate = function() {
            return this.replace(/-/g, "/");
        }
        String.prototype.toShortDate = function() {
            return this.split(' ')[0];
        }
        // array map
        if(!Array.prototype.map) {
            Array.prototype.map = function(callback, thisArg) {
                var T, A, k;
                if(this == null) {
                    throw new TypeError(' this is null or not defined');
                }
                var O = Object(this);
                var len = O.length >>> 0;
                if(typeof callback !== 'function') {
                    throw new TypeError(callback + ' is not a function');
                }
                if(arguments.length > 1) {
                    T = thisArg;
                }
                A = new Array(len);
                k = 0;
                while (k < len) {
                    var kValue, mappedValue;
                    if (k in O) {
                        kValue = O[k];
                        mappedValue = callback.call(T, kValue, k, O);
                        A[k] = mappedValue;
                    }
                    k++;
                }
                return A;
            };
        }
        // array filter
        if(!Array.prototype.filter) {
            Array.prototype.filter = function(fun/*, thisArg*/) {
                if(this === void 0 || this === null) {
                    throw new TypeError();
                }
                var t = Object(this);
                var len = t.length >>> 0;
                if (typeof fun !== 'function') {
                    throw new TypeError();
                }
                var res = [];
                var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
                for(var i = 0; i < len; i++) {
                    if (i in t) {
                        var val = t[i];
                        if(fun.call(thisArg, val, i, t)) {
                            res.push(val);
                        }
                    }
                }
                return res;
            };
        }
        return {
            // get 请求的 数据和url 拼接
            splitGet: function(url, datas) {
                var strs = "";
                if((typeof datas).toLocaleLowerCase() !== 'object') strs = datas;
                else {
                    var str=[];
                    for(var p in datas){
                        str.push(encodeURIComponent(p)+'='+encodeURIComponent(datas[p]))
                    }
                    strs = str.join('&');
                }
                return url + "?" + strs;
            },
            getSelect: function(arr, list) {
                var index = arr.indexOf(list);
                if (index !== -1) {
                    arr.splice(index, 1);
                } else {
                    arr.push(list);
                }
                return arr;
            },
            //解决js浮点运算bug
            /* 除 */
            accDiv: function(arg1, arg2) {
                var t1 = 0,
                    t2 = 0,
                    r1, r2;
                try {
                    t1 = arg1.toString().split(".")[1].length
                } catch (e) {}
                try {
                    t2 = arg2.toString().split(".")[1].length
                } catch (e) {}
                r1 = Number(arg1.toString().replace(".", ""))
                r2 = Number(arg2.toString().replace(".", ""))
                return (r1 / r2) * Math.pow(10, t2 - t1);
            },
            /* 乘 */
            accMul: function(arg1, arg2) {
                var m = 0,
                    s1 = arg1.toString(),
                    s2 = arg2.toString();
                try {
                    m += s1.split(".")[1].length
                } catch (e) {}
                try {
                    m += s2.split(".")[1].length
                } catch (e) {}
                return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
            },
            compareGreaterTime: function(date1, date2) {
                var _date1 = new Date(date1.formatDate()).getTime();
                var _date2 = new Date(date2.formatDate()).getTime();
                return _date1 > _date2;
            },
            compareLittleTime: function(date1, date2) {
                var _date1 = new Date(date1.formatDate()).getTime();
                var _date2 = new Date(date2.formatDate()).getTime();
                return _date1 < _date2;
            },
            addLoading: function() {
                angular.element('.shade-layer').css({'height': document.body.scrollHeight + 'px'}).removeClass('ng-hide').addClass('ng-show');
            },
            removeLoading: function() {
                angular.element('.shade-layer').removeClass('ng-show').addClass('ng-hide');
            },
            formatDate: function(date, flag){
                var now = new Date(date);
                var year = now.getFullYear();
                var month = now.getMonth() < 9 ? '0'+ (now.getMonth()+1) : now.getMonth()+1;
                var date = now.getDate() < 10 ? '0'+now.getDate() : now.getDate();
                var hour = now.getHours();
                var minute = now.getMinutes();
                var second = now.getSeconds();
                if(flag){
                    return year + '-' + month + '-' + date + ' ' +hour+':'+minute+':'+second;
                } else {
                    return year + '-' + month + '-' + date;
                }

            },
            // extend: function(_this, currObj, theObj) {},
            type: function(obj) {
                return obj == null ? String(obj) : (classtype[Object.prototype.toString.call(obj)] || "object");
            }
        }
    })();


    function UIService(params) {
        this.version = '2.0';
        this.constructor = UIService;
        var _this = this;
        if(appCommon.type(params) !== 'array') {
            this.extend(params);
        }else {
            params.map(function(obj) {
                _this.extend(obj);
            });
        }
    }
    UIService.prototype.extend = function(obj) {
        angular.extend(this, this, obj)
    }

    return new UIService([appAjax, appDom, appCommon]);

}]);

